﻿using ProgrammingEducationSystem.Models;
using ProgrammingEducationSystem.Repository.IRepository;
using ProgrammingEducationSystem.Services.IServices;
using Microsoft.EntityFrameworkCore;
using System.Security.Claims;

namespace ProgrammingEducationSystem.Services
{
    public class CoursesService : ICoursesService
    {
        private readonly ICourseRepository _courseRepository;
        private readonly IStuAndClassRepository _stuAndClassRepository;
        private readonly IEndClassRepository _endClassRepository;
        public CoursesService(ICourseRepository courseRepository, IStuAndClassRepository stuAndClassRepository)
        {
            _courseRepository = courseRepository;
            _stuAndClassRepository = stuAndClassRepository;
        }
        public async Task<List<Course>?> AllAsync()
        {
            return await _courseRepository.FindAllAsync();
        }

        public async Task<Course?> GetByIdAsync(Guid courseId)
        {
            return await _courseRepository.FindAsync(courseId);
        }

        public async Task<List<Course>?> GetByTeacherIdAsync(string teacherId)
        {
            return await _courseRepository.FindByTeacherIdAsync(teacherId);
        }

        public async Task<List<Course>?> GetByStudentIdAsync(string studentId)
        {
            return await _courseRepository.FindByStudentIdAsync(studentId);
        }

        public async Task<List<Course>?> GetByClassIdAsync(Guid classId)
        {
            return await _courseRepository.GetByClassIdAsync(classId);
        }

        public async Task<List<Course>?> GetByClassTypeAsync(Guid classTypeId)
        {
            return await _courseRepository.GetByClassTypeAsync(classTypeId);
        }

        public async Task<List<Course>?> GetByClassTypeAsync(string classTypeName)
        {
            return await _courseRepository.GetByClassTypeNameAsync(classTypeName);
        }

        public async Task<List<Course>?> GetByStuAndClassTypeAsync(string stuId, Guid classTypeId)
        {
            var stu = await _stuAndClassRepository.GetByStudentIdAsync(stuId);
            var cly = await _courseRepository.GetByClassTypeAsync(classTypeId);
            if (stu == null || cly == null) {
                return null;            
            }
            var result = cly.Where(c=> stu.Any(s=> s.ClassId == c.ClassId)).ToList();
            return result;
        }

        public async Task<List<Course>?> GetByTeaAndClassTypeAsync(string teaId, Guid classTypeId)
        {
            var tea = await _courseRepository.FindByTeacherIdAsync(teaId);
            var cly = await _courseRepository.GetByClassTypeAsync(classTypeId);
            if(tea == null || cly == null) {
                return null;
            }
            var result = cly.Where(c => tea.Any(t => t.ClassId == c.ClassId)).ToList();
            return result;
        }

        public async Task<List<Course>?> GetByTeaAndExpiredAsync(string teaId)
        {
            var tea = await _courseRepository.FindByTeacherIdAsync(teaId);
            var ecs = await _endClassRepository.FindAllAsync();
            if (tea == null) {
                 return null;
            }
            var result = tea.Where(c => ecs.Any(e => e.ClassId == c.Id)).ToList();
            return result;
        }

        public async Task<List<Course>?> GetByTeaAndNotExpiredAsync(string teaId)
        {
            var tea = await _courseRepository.FindByTeacherIdAsync(teaId);
            var ecs = await _endClassRepository.FindAllAsync();
            if (tea == null)
            {
                return null;
            }
            var result = tea.Where(c => !ecs.Any(e => e.ClassId == c.Id)).ToList();
            return result;
        }

        public async Task<List<Course>?> GetByStuAndExpiredAsync(string stuId)
        {
            var stu = await _courseRepository.FindByStudentIdAsync(stuId);
            var ecs = await _endClassRepository.FindAllAsync();
            if (stu == null)
            {
                return null;
            }
            var result = stu.Where(c => ecs.Any(e => e.ClassId == c.Id)).ToList();
            return result;
        }

        public async Task<List<Course>?> GetByStuAndNotExpiredAsync(string stuId)
        {
            var stu = await _courseRepository.FindByStudentIdAsync(stuId);
            var ecs = await _endClassRepository.FindAllAsync();
            if (stu == null)
            {
                return null;
            }
            var result = stu.Where(c => !ecs.Any(e => e.ClassId == c.Id)).ToList();
            return result;
        }

        public async Task<List<Course>?> GetByClassAndExpiredAsync(Guid classId)
        {
            var cls = await _courseRepository.GetByClassIdAsync(classId);
            var ecs = await _endClassRepository.FindAllAsync();
            if (cls == null)
            {
                return null;
            }
            var result = cls.Where(c => ecs.Any(e => e.ClassId == c.Id)).ToList();
            return result;
        }

        public async Task<List<Course>?> GetByClassAndNotExpiredAsync(Guid classId)
        {
            var cls = await _courseRepository.GetByClassIdAsync(classId);
            var ecs = await _endClassRepository.FindAllAsync();
            if (cls == null)
            {
                return null;
            }
            var result = cls.Where(c => !ecs.Any(e => e.ClassId == c.Id)).ToList();
            return result;
        }
    

        public async Task DeleteAsync(Guid id)
        {
            var Id = await _courseRepository.FindAsync(id);
            _courseRepository.Delete(Id);
        }

        public async Task AddAsync(Course course)
        {
            await _courseRepository.AddAsync(course);
        }

        public void Update(Course course)
        {
            _courseRepository.Update(course);
        }

        public async Task<bool> SaveAsync()
        {
            return await _courseRepository.SaveAsync();
        }

        
    }
}


